package com.asder.tool.generator.utils;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * sql 转换
 */
public class SqlUtil {

    /**
     * 原sql 用来 取 表名 和 字段 名
     */
    private String sql;
    /**
     * 自定义的 参数 where 条件 所需的 值
     */
    private Map<String, String> map;
    /**
     * 字段 名 数组
     */
    private String[] fields;
    /**
     * 错误信息
     */
    private String errInfo = "";

//    public String getErrInfo() {
//        return errInfo;
//    }

    public void setErrInfo(String errInfo) {
        this.errInfo = errInfo;
    }

//    public String getSql() {
//        return sql;
//    }

    public void setSql(String sql) {
        this.sql = sql;
    }

//    public Map<String, String> getMap() {
//        return map;
//    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

//    public String[] getFields() {
//        return fields;
//    }

    public void setFields(String[] fields) {
        this.fields = fields;
    }

    /**
     * @Description: 插入 语句 转换
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 sql
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertInsertSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        return StrUtil.format("insert into "
                + getTableName(sql)
                + "("
                + ArrayUtil.join(fields, ",")
                + ")values('{"
                + ArrayUtil.join(fields, "}','{")
                + "}')", map);
    }

    /**
     * @Description: 更新 语句 转换
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 例子 sql update testAset t1='xx',set t2='xxt2' where 1=1 and t1='xx' and t2='xxt2'
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertUpdateSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        return StrUtil.format("update "
                        + getTableName(sql)
                        + " "
                        + getUpdateSet(fields)
                        + getWhere(fields, map)
                , map);
    }

    /**
     * @Description: 删除 语句 转换
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 sql 例子 delete from testA where 1=1 and t1='xx' and t2='xxt2'
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertDeleteSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        return StrUtil.format("delete from "
                        + getTableName(sql)
                        + getWhere(fields, map)
                , map);
    }

    /**
     * @Description: 查询 语句 转换
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 sql 例子 select t1,t2 from testA where 1=1 and t1='xx' and t2='xxt2'
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertSelectSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }

        return StrUtil.format("select "
                        + getSelect()
                        + " from "
                        + getTableName(sql)
                        + getJoin(map)
                        + getLeftJoin(map)
                        + getWhere(fields, map)
                        + getGroupBy(map)
                        + getOrderBy(map)
                        + getLimit(map)
                , map);
    }

    /**
     * @Description: 查询 语句 转换 自定义 select
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 sql 例子 select t1,t2 from testA where 1=1 and t1='xx' and t2='xxt2'
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertSelectDivSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        String[] fields = ReUtil.get("(?<=\\()(.+?)(?=\\))", sql, 1)
                .replaceAll(" ", "").split(",");

        return StrUtil.format(getDivSelect(map)
                        + " from "
                        + getTableName(sql)
                        + getJoin(map)
                        + getLeftJoin(map)
                        + getWhere(fields, map)
                        + getGroupBy(map)
                        + getOrderBy(map)
                        + getLimit(map)
                , map);
    }

    /**
     * @Description: 查询 语句 转换 合计 - 列需转换的 sql
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: 数据库 识别的 sql 例子 select t1,t2 from testA where 1=1 and t1='xx' and t2='xxt2'
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertSelectAllSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        return StrUtil.format("select "
                        + getSelect()
                        + " from "
                        + getTableName(sql)
                        + getJoin(map)
                        + getLeftJoin(map)
                        + getWhere(fields, map)
                , map);
    }

    /**
     * @Description: 获取 select 中的 内容
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/5
     */
    public String getSelect() {
        String[] fields = ReUtil.get("(?<=\\()(.+?)(?=\\))", sql, 1)
                .replaceAll(" ", "").split(",");
        String selectSql = ArrayUtil.join(fields, ",");

        for (String s2 : map.keySet()) {

            // sql_select_ 普通类型 只允许 格式转换 不允许聚合函数
            if (s2.contains("sql_select_")) {
                for (String s : map.keySet()) {
                    if (s.equals("format_date")) {
                        for (String s1 : map.get(s).split(",")) {
                            selectSql = selectSql.replace(s1, "date_format(" + s1 + ",'%Y-%m-%d') as " + s1);
                        }
                    }
                    if (s.equals("format_time")) {
                        for (String s1 : map.get(s).split(",")) {
                            selectSql = selectSql.replace(s1, "date_format(" + s1 + ",'%Y-%m-%d  %H:%i:%s') as " + s1);
                        }
                    }
                }
                return selectSql;
            }
        }

        for (String s : map.keySet()) {
            if (s.equals("sum")) {
                for (String s1 : map.get(s).split(",")) {
                    selectSql = selectSql.replace(s1, "sum(" + s1 + ") as " + s1);
                }
            }
            if (s.equals("format_date")) {
                for (String s1 : map.get(s).split(",")) {
                    selectSql = selectSql.replace(s1, "date_format(" + s1 + ",'%Y-%m-%d') as " + s1);
                }
            }
            if (s.equals("format_time")) {
                for (String s1 : map.get(s).split(",")) {
                    selectSql = selectSql.replace(s1, "date_format(" + s1 + ",'%Y-%m-%d  %H:%i:%s') as " + s1);
                }
            }
        }
        return selectSql;
    }

    /**
     * @Description: count(1)  统计数量
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String convertCountSql(String sql, Map<String, String> map) {
        paramsCheck(sql, map);
        if (!errInfo.equals("")) {
            return errInfo;
        }
        return StrUtil.format("select count(1) "
                + " from "
                + getTableName(sql)
                + getJoin(map)
                + getLeftJoin(map)
                + getWhere(fields, map)
                + getGroupBy(map), map);
    }

    /**
     * @Description: 获取表名
     * @Param: sql 例子 testA(t1,t2,t3,t4)
     * @return: 表名
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getTableName(String sql) {
        return ReUtil.get("(.+?)(?=\\()", sql, 1);
    }

    /**
     * @Description: 获取 有效的字段名
     * @Param: sql: 例子 testA(t1,t2,t3,t4) map 参数
     * @return: String[] 字段名
     * @Author: zy
     * @date: 2020/4/4
     */
    public String[] getFields(String sql, Map<String, String> map) {
        String[] fields = ReUtil.get("(?<=\\()(.+?)(?=\\))", sql, 1)
                .replaceAll(" ", "").split(",");
        for (String s : fields) {
            if (map.get(s) == null || map.get(s).equals("")) {
                fields = ArrayUtil.removeEle(fields, s);
            }
        }
        return fields;
    }

    /**
     * @Description: map 参数 去除 首尾 空格
     * @Param: map 前台传递的参数
     * @return: 转换后的 map
     * @Author: zy
     * @date: 2020/4/4
     */
    public Map<String, String> getParamsMap(Map<String, String> map) {
        Map<String, String> resMap = new HashMap<>();
        for (String s : map.keySet()) {
            if (map.get(s) != null && !map.get(s).equals("")) {
                resMap.put(s, StrUtil.trim(StrUtil.toString(map.get(s))));
            }
        }
        return resMap;
    }

    /**
     * @Description: 获取 更新 语句的 set
     * @Param: arry
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getUpdateSet(String[] arry) {
        StringBuilder res = new StringBuilder();
        for (String s : arry) {
            res.append(StrUtil.join(s, "set ", "={", "},"));
        }
        return res.toString().substring(0, res.length() - 1);
    }

    /**
     * @Description: 查询 条件 limit
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getLimit(Map<String, String> map) {
        if (map.get("page") != null && !map.get("page").equals("")) {
            return " limit  "
                    + new BigDecimal(map.get("page")).subtract(BigDecimal.ONE)
                    .multiply(new BigDecimal(map.get("limit")))
                    + "," + new BigDecimal(map.get("page"))
                    .multiply(new BigDecimal(map.get("limit")));
        }
        return "";
    }

    /**
     * @Description: 查询 条件 left join
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getLeftJoin(Map<String, String> map) {
        if (map.get("leftJoin") != null && !map.get("leftJoin").equals("")) {
            return " left join  " + map.get("leftJoin");
        }
        return "";
    }

    /**
     * @Description: 查询 条件 join
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getJoin(Map<String, String> map) {
        if (map.get("join") != null && !map.get("join").equals("")) {
            return " join  " + map.get("join");
        }
        return "";
    }

    /**
     * @Description: 查询 条件  group by 分组
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getGroupBy(Map<String, String> map) {
        if (map.get("groupBy") != null && !map.get("groupBy").equals("")) {
            return " group by " + map.get("groupBy");
        }
        return "";
    }

    public String getDivSelect(Map<String, String> map) {
        if (map.get("select") != null && !map.get("select").equals("")) {
            return " select " + map.get("select");
        }
        return "";
    }


    public String getOrderBy(Map<String, String> map) {
        if (map.get("orderBy") != null && !map.get("orderBy").equals("") && sql.contains(map.get("orderBy"))) {
            if (map.get("sidx") != null && !map.get("sidx").equals("") && sql.contains(map.get("sidx"))) {
                return " order by " + map.get("sidx") + " " + map.get("order") + "," + map.get("orderBy") + " ";
            }
            return " order by " + map.get("orderBy");
        }
        return "";
    }

    /**
     * @Description: 获取 where 语句  只有 =
     * @Param: arry  map 前台的值
     * @return: where 查询 条件
     * @Author: zy
     * @date: 2020/4/4
     */
    public String getWhere(String[] arry, Map<String, String> map) {
        StringBuilder res = new StringBuilder();
        res.append(" where 1=1");
        for (String s : arry) {
            for (String s1 : map.keySet()) {
                // 参数 直接 =
                if (s.equals(s1)) {
                    res.append(StrUtil.join(StrUtil.toString(s), " and ", "='{", "}'"));
                }
            }

        }

        for (String s1 : map.keySet()) {
            // 参数 直接 !=
            for (String s : s1.split("-")) {
                if (s.equals("!") && sql.contains(s1.split("\\-")[0])) {
                    res.append(StrUtil.join(StrUtil.toString(s1.split("\\-")[0]),
                            " and ", "!='" + map.get(s1) + "'"));

                }
                // like
                if (s.equals("like") && sql.contains(s1.split("\\-")[0])) {
                    res.append(StrUtil.join(StrUtil.toString(s1.split("\\-")[0]),
                            " and ", " like '%" + map.get(s1) + "%'"));
                }
                // not like
                if (s.equals("not_like") && sql.contains(s1.split("\\-")[0])) {
                    res.append(StrUtil.join(StrUtil.toString(s1.split("\\-")[0]),
                            " and ", " not like '%" + map.get(s1) + "%'"));
                }
                // in
                if (s.equals("in") && sql.contains(s1.split("\\-")[0])) {
                    res.append(StrUtil.join(StrUtil.toString(s1.split("\\-")[0]),
                            " and ", " in (" + map.get(s1) + ")"));
                }
                // not in
                if (s.equals("not_in") && sql.contains(s1.split("\\-")[0])) {
                    res.append(StrUtil.join(StrUtil.toString(s1.split("\\-")[0]),
                            " and ", " not in (" + map.get(s1) + ")"));
                }
                // between
                if (s.equals("between") && sql.contains(s1.split("\\-")[0])) {
                    res.append(" and  " + s1.split("\\-")[0]
                            + " between '" + map.get(s1).split("\\+")[0]
                            + "' and '" + map.get(s1).split("\\+")[1] + "' ");
                }
                // not between
                if (s.equals("not_between") && sql.contains(s1.split("\\-")[0])) {
                    res.append(" and  " + s1.split("\\-")[0]
                            + " not between '" + map.get(s1).split("\\+")[0]
                            + "' and '" + map.get(s1).split("\\+")[1] + "' ");
                }
            }

        }

        if(!map.get("ei_id").equals("false")){
            res.append(" and " + getTableName(sql) + ".ei_id=" + map.get("ei_id"));
        }

        return res.toString();
    }

    /**
     * @Description: 参数 检查
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/4
     */
    public void paramsCheck(String sql, Map<String, String> map) {
        if (sql == null) {
            setErrInfo("sql 为空");
            return;
        }
        if (map == null) {
            setErrInfo("map 为空");
            return;
        }

        setSql(sql.toLowerCase());
        setMap(getParamsMap(map));
        setFields(getFields(sql, map));
    }

    /**
     * @Description: 主方法
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/5
     */
    public String getSql(Map<String, String> map) {
        if (map.get("ei_id") == null || map.get("ei_id") == "") {
            return "缺少 ei_id";
        }
        map = removeMapPre(map);
       // System.out.println("map1:" + JSON.toJSON(map));
        String res = "";
        for (String s : map.keySet()) {
            if (s.contains("sql_insert_")) {
                res = convertInsertSql(map.get(s), map);
            }
            if (s.contains("sql_count_")) {
                res = convertCountSql(map.get(s), map);
            }
            if (s.contains("sql_update_")) {
                res = convertUpdateSql(map.get(s), map);
            }
            if (s.contains("sql_delete_")) {
                res = convertDeleteSql(map.get(s), map);
            }
            if (s.contains("sql_select_")) {
                res = convertSelectSql(map.get(s), map);
            }
            if (s.contains("sql_selectAll_")) {
                res = convertSelectAllSql(map.get(s), map);
            }
            if (s.contains("sql_selectDiv_")) {
                res = convertSelectDivSql(map.get(s), map);
            }
        }
//        System.out.println("key:" + map.get("key"));
        System.out.println("sql:" + res);
        return res;
    }

    /**
     * @Description: 移除map 前缀
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/5
     */
    public Map<String, String> removeMapPre(Map<String, String> map) {
        //System.out.println("map0:" + JSON.toJSON(map));
        Object[][] mapArry = MapUtil.toObjectArray(map);

        for (Object[] objects : mapArry) {
            // 将 sql 与 参数分离
            if (objects[0].toString().contains("sql_")) {
                if (objects[1].toString().contains("$")) {
                    String[] Array = objects[1].toString().split("\\$");
                    map.put(objects[0].toString(), Array[0]);

                    StringBuffer jsonData = new StringBuffer();
                    jsonData.append(StrUtil.removeAll(StrUtil.removeAll(Array[1], "\\r\\n"), "\\"));

                    JSONObject jsonObject = JSONObject.parseObject(jsonData.toString());
                    System.out.println("JSON0:" + JSON.toJSON(jsonObject));
                    for (String s : jsonObject.keySet()) {
                        map.put(s, jsonObject.getString(s));


                    }
                }
            }
        }
        mapArry = MapUtil.toObjectArray(map);
        String preName = getMapPre(map, "sql_pre");

        for (Object[] objects : mapArry) {
            if (objects[0].toString().contains(preName)) {
                map.put(objects[0].toString().replace(preName, "")
                        , map.get(objects[0].toString()));
            }
        }

        return map;
    }

    /**
     * @Description: 获取 前缀
     * @Param:
     * @return:
     * @Author: zy
     * @date: 2020/4/5
     */
    public static String getMapPre(Map<String, String> map, String res) {


        for (String s : map.keySet()) {
            if (s.contains(res)) {
                res = map.get(s);
                return res;
            }

        }
        return "";
    }

    public static void main(String[] args) {

        Map<String, String> paramsMap5 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("t1x", "xx  t1x");
            put("sql_count_good", "tEstA(t1,t2,t3,t4)");
            put("ei_id", "false");
        }};

        new SqlUtil().getSql(paramsMap5);
        Map<String, String> paramsMap = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("t1x", "xx  t1x");
            put("sql_insert_good", "tEstA(t1,t2,t3,t4)");
            put("ei_id", "false");
        }};

        new SqlUtil().getSql(paramsMap);
        Map<String, String> paramsMap2 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("t1x", "xx  t1x");
            put("sql_update_good", "tEstA(t1,t2,t3,t4)");
            put("ei_id", "false");
        }};

        new SqlUtil().getSql(paramsMap2);
        Map<String, String> paramsMap3 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("t1x", "xx  t1x");
            put("t3-!", "xxx ");
            put("t3-like", "xxx ");
            put("t3-not_like", "xxx ");
            put("t3-in", "xxx ");
            put("t3-not_in", "xxx ");
            put("t3-between", "xx+x ");
            put("t3-not_between", "xx+x ");
            put("ei_id", "false");

            put("sql_delete_good", "tEstA(t1,t2,t3,t4)");
        }};

        new SqlUtil().getSql(paramsMap3);
        //  sql 拼接参数 前缀 sql_good
        Map<String, String> paramsMap4 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("limit", "100");
            put("page", "1");

            put("sql_pre", "sql_good_");
            put("t1x", "xx  t1x");
            put("sql_good_leftJoin", " testb on testa.ei_id = testb.ei_id  ");
            put("sql_good_join", " testb on testa.ei_id = testb.ei_id    ");
            put("sql_good_sum", "t1,t2");
            put("sql_good_format_date", "t5");
            put("sql_good_format_time", "t6");
            put("t3-between", "xx+x ");
            put("groupBy", "t3");
            put("orderBy", "t3");
            put("ei_id", "false");
            put("sql_select_good", "tEstA(t1,t2,t3,t4,t5)");
        }};

        new SqlUtil().getSql(paramsMap4);
        //  sql 拼接参数 前缀 sql_good
        Map<String, String> paramsMap7 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("limit", "100");
            put("page", "2");

            put("sql_pre", "sql_good_");
            put("t1x", "xx  t1x");
            put("sql_good_leftJoin", " testb on testa.ei_id = testb.ei_id  ");
            put("sql_good_join", " testb on testa.ei_id = testb.ei_id    ");
            put("sql_good_sum", "t1,t2");
            put("sql_good_format_date", "t5");
            put("sql_good_format_time", "t6");
            put("ei_id", "false");
            put("sql_selectAll_good", "tEstA(t1,t2,t3,t4,t5)");
        }};

        new SqlUtil().getSql(paramsMap7);
        //  sql 拼接参数 前缀 sql_good
        Map<String, String> paramsMap8 = new HashMap<String, String>() {{
            put("t1", "xx  ");
            put("t2", " xxt2  ");
            put("limit", "100");
            put("page", "2");
            put("select", "t1,t2,t3,t222");
            put("sql_pre", "sql_good_");
            put("t1x", "xx  t1x");
            put("ei_id", "123456");
            put("sql_good_leftJoin", " testb on testa.ei_id = testb.ei_id  ");
            put("sql_good_join", " testb on testa.ei_id = testb.ei_id    ");
            put("sql_good_sum", "t1,t2");
            put("sql_good_format_date", "t5");
            put("sql_good_format_time", "t6");

            put("sql_selectDiv_good", "tEstA(t1,t2,t3,t4,t5)");
        }};
        new SqlUtil().getSql(paramsMap8);
        // System.out.println("sql: " + JSON.toJSON(new SqlUtil().getSql(paramsMap8)));



        // new SqlUtil().selectTableInfo();
    }


    public void selectTableInfo(){
        // 数据库查询- 查询 表明及备注  自动生成 sql 转换 map 增删改查
        // 分割符号 ,,  对应值  A=== BCD
        //
        String simple = "name==='zy',,,age===23";
        Map<String, String> paramsMap10 = new HashMap<String, String>();
        for (String s : simple.split(",,,")) {
            paramsMap10.put(s.split("===")[0], s.split("===")[1]);
        }
        System.out.println("map :" + JSON.toJSON(paramsMap10));
        try {
            // 库名称
            String table_schema = "xdbase";
            // 表名称
            String table_name = "t_base_area";
            // 表名称及备注查询
            List<Entity> result = Db.use()
                    .query("select table_name,table_comment " +
                            " from information_schema.tables " +
                            "where table_schema='"+table_schema+"'");
            System.out.println("表名称及备注查询 :");
            result.forEach(item -> System.out.println(item));
            System.out.println("tableName: " + result.get(0).getTableName().getClass().toString());
            System.out.println("fieldNames: " + result.get(0).getFieldNames().getClass().toString());
            System.out.println("fields: " + result.get(0).getClass().toString());

//            result.forEach(item -> System.out.println(item.get(item.getFieldNames().toArray()[0]) +"="
//                        + item.get(item.getFieldNames().toArray()[1])));
//            System.out.println(result.get(0).getFieldNames());
//            result.forEach(item -> {System.out.println();
//                    item.getFieldNames().forEach(item2-> System.out.print(item.get(item2).toString()+ ","));});


            // 字段及备注查询
            List<Entity> result2 = Db.use()
                    .query("select column_name,column_comment  " +
                            " from information_schema.columns " +
                            "where table_schema='"+table_schema+"' " +
                            "and table_name='"+table_name+"' ");
            System.out.println("字段及备注查询 :");
            result2.forEach(item -> System.out.println(item));

            // 查询 表名 和字段
            String result3 = Db.use()
                    .queryString("select CONCAT(table_schema,'(',GROUP_CONCAT(column_name),')') as id " +
                            " from information_schema.columns  " +
                            "where table_schema='"+table_schema+"' " +
                            "and table_name='"+table_name+"' ");
            System.out.println("查询 表名 和字段 :");
            System.out.println(result3);

        }catch (Exception e){
            System.out.println(e);
        }
    }

}
